#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>

#define SNAKE_MAX_LENGTH 20
#define SNAKE_HEAD 'H'
#define SNAKE_BODY 'X'
#define BLANK_CELL ' '
#define SNAKE_FOOD '$'
#define WALL_CELL '*'
#
int snake_head_direction;//1:up,2:right,3:down,4:left


//snake stepping: 0:no move,1:up,2:right,3:down,4:left,the direction of moving can't contradict the direction of snake head;
void init(void);
void snakeMove(int direction);
void put_money(void);
void output(void);
void gameover(void);

char map[12][12]={
    "************",
    "*XXXXH     *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "************"
};

int snakeX[SNAKE_MAX_LENGTH]={1,2,3,4,5};
int snakeY[SNAKE_MAX_LENGTH]={1,1,1,1,1};
int snakeLength = 5;
int FOODX=0;
int FOODY=0;
int vis[12][12]={0};//标记数组，1:SNAKE_BODY,2:SNAKE_HEAD,3:FOOD
int gameOver=0;
void init(void){
    snake_head_direction=2;
    for(int i=1;i<snakeLength;i++){
        vis[1][i]=1;
    }
    vis[1][snakeLength]=2;
    for(int i=0;i<12;i++){
        vis[0][i]=1;
        vis[11][i]=1;
        vis[i][0]=1;
        vis[i][11]=1;
    }
}
void put_money(void){
    srand(time(NULL));
     FOODY=rand()%12;
     FOODX=rand()%12;
    while(vis[FOODY][FOODX]!=0){
         FOODX=rand()%12;
         FOODY=rand()%12;
    }
    vis[FOODY][FOODX]=3;
}
void snakeMove(int direction){
    switch(direction){
        case 0: break;
        case 1:{//向上
            if(snake_head_direction==3){
                printf("invalid operation!,please enter a new direction:\n");
                return;//the direction of moving can't contradict the snake head direction
            }else{
                vis[snakeY[0]][snakeX[0]]=0;//body的最后一个位置的vis值设置为0
                vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]=1;
                for(int i=1;i<snakeLength;i++){
                    snakeX[i-1]=snakeX[i];
                    snakeY[i-1]=snakeY[i];
                }//snake_body往前移动一步，snake_head向上移动一步，snake_head_direction改为向上
                snakeY[snakeLength-1]--;
                snake_head_direction=1;
                if(vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]==1){
                    gameOver=1;
                }
                vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]=2;
                break;
            }
        }
        case 2:{
            if(snake_head_direction==4){
                printf("invalid operation!,please enter a new direction:\n");
                return;//the direction of moving can't contradict the snake head direction
            }else{
                vis[snakeY[0]][snakeX[0]]=0;
                vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]=1;
                for(int i=1;i<snakeLength;i++){
                    snakeX[i-1]=snakeX[i];
                    snakeY[i-1]=snakeY[i];
                }//snake_body往前移动一步，snake_head向右移动一步，snake_head_direction改为向右
                snakeX[snakeLength-1]++;
                snake_head_direction=2;
                if(vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]==1){
                    gameOver=1;
                }
                vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]=2;

                break;
            }
        }
        case 3:{
            if(snake_head_direction==1){
                printf("invalid operation!,please enter a new direction:\n");
                return;
            }else{
                vis[snakeY[0]][snakeX[0]]=0;
                vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]=1;
                for(int i=1;i<snakeLength;i++){
                    snakeX[i-1]=snakeX[i];
                    snakeY[i-1]=snakeY[i];
                }//snake_body往前移动一步，snake_head向下移动一步，snake_head_direction改为向下
                snakeY[snakeLength-1]++;
                snake_head_direction=3;
                if(vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]==1){
                    gameOver=1;
                }
                vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]=2;

                break;
            }
        }
        case 4:{
            if(snake_head_direction==2){
                printf("invalid operation!,please enter a new direction:\n");
                return;
            }else{
                vis[snakeY[0]][snakeX[0]]=0;
                vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]=1;
                for(int i=1;i<snakeLength;i++){
                    snakeX[i-1]=snakeX[i];
                    snakeY[i-1]=snakeY[i];
                }
                snakeX[snakeLength-1]--;
                snake_head_direction=4;
                if(vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]==1){
                    gameOver=1;
                }
                vis[snakeY[snakeLength-1]][snakeX[snakeLength-1]]=2;

                break;
            }
        }
        default:break;
    }
    if(gameOver==0){
        output();}
}



void output(void){
    int i,j;
    for(i=0;i<12;i++){
    for(j=0;j<12;j++){
        if(i==0||i==11||j==0||j==11){
            printf("*");
        }else if(vis[i][j]==1){
            printf("X");
        
        }else if(vis[i][j]==2){
            printf("H");
        
        }else if(vis[i][j]==3){
            printf("$");
        }else{
            printf(" ");
        }
    }
        printf("\n");
    }
}

int main(){
    init();
    char c;
    output();
    while(gameOver!=1){
        scanf("%c",&c);
        printf("\n");
        switch(c){
            case 'A':{snakeMove(4);break;}
            case 'D':{snakeMove(2);break;}
            case 'W':{snakeMove(1);break;}
            case 'S':{snakeMove(3);break;}
            default:break;
        }
    }
    printf("Game Over!\n");
    return 0;
}
